from flask import render_template, request, jsonify
from ..app import app, db, TestCase, TestSuite, TestResult
from datetime import datetime
import json
import traceback

@app.route('/')
def index():
    """
    首页
    """
    return render_template('index.html')

@app.route('/testcases')
def testcases():
    """
    测试用例列表页面
    """
    return render_template('testcases.html')

@app.route('/api/testcases', methods=['GET'])
def get_testcases():
    """
    获取所有测试用例
    """
    try:
        # 只获取未删除的测试用例
        all_testcases = TestCase.query.filter_by(is_deleted=False).all()
        return jsonify([tc.to_dict() for tc in all_testcases])
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/api/testcases', methods=['POST'])
def create_testcase():
    try:
        data = request.get_json()
        
        # 设置默认优先级为P3
        priority = data.get('priority', 'P3')
        if priority not in ['P1', 'P2', 'P3', 'P4']:
            priority = 'P3'
        
        testcase = TestCase(
            name=data.get('name'),
            description=data.get('description'),
            url=data.get('url'),
            steps=json.dumps(data.get('steps', [])),
            priority=priority
        )
        
        # 处理前置条件
        precondition_test_case_ids = data.get('precondition_test_case_ids', [])
        if precondition_test_case_ids:
            # 过滤掉当前测试用例自身（在创建时无法确定ID，所以只验证有效性）
            valid_preconditions = TestCase.query.filter(
                TestCase.id.in_(precondition_test_case_ids), 
                TestCase.is_deleted == False
            ).all()
            testcase.precondition_test_cases = valid_preconditions
        
        # 处理关联测试套件
        test_suite_ids = data.get('test_suite_ids', [])
        if test_suite_ids:
            valid_suites = TestSuite.query.filter(TestSuite.id.in_(test_suite_ids), TestSuite.is_deleted==False).all()
            invalid_ids = set(test_suite_ids) - set(ts.id for ts in valid_suites)
            if invalid_ids:
                return jsonify({'error': f'Test suites not found: {list(invalid_ids)}'}), 404
                
            testcase.test_suites = valid_suites
        
        db.session.add(testcase)
        db.session.commit()
        return jsonify(testcase.to_dict())
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

@app.route('/api/testcases/<int:testcase_id>', methods=['GET'])
def get_testcase(testcase_id):
    """
    获取单个测试用例
    """
    try:
        # 只获取未删除的测试用例
        testcase = TestCase.query.filter_by(id=testcase_id, is_deleted=False).first_or_404()
        return jsonify(testcase.to_dict())
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/api/testcases/<int:testcase_id>', methods=['PUT'])
def update_testcase(testcase_id):
    try:
        testcase = TestCase.query.filter_by(id=testcase_id, is_deleted=False).first_or_404()
        data = request.get_json()
        
        if 'name' in data:
            testcase.name = data['name']
        if 'description' in data:
            testcase.description = data['description']
        if 'url' in data:
            testcase.url = data['url']
        if 'steps' in data:
            testcase.steps = json.dumps(data['steps'])
        if 'priority' in data:
            priority = data['priority']
            if priority in ['P1', 'P2', 'P3', 'P4']:
                testcase.priority = priority
        testcase.updated_at = datetime.utcnow()
        
        # 处理前置条件
        if 'precondition_test_case_ids' in data:
            precondition_test_case_ids = data['precondition_test_case_ids']
            if precondition_test_case_ids is None:
                testcase.precondition_test_cases = []
            elif isinstance(precondition_test_case_ids, list):
                valid_preconditions = TestCase.query.filter(
                    TestCase.id.in_(precondition_test_case_ids), 
                    TestCase.is_deleted == False,
                    TestCase.id != testcase.id  # 过滤掉当前测试用例自身
                ).all()
                invalid_ids = set(precondition_test_case_ids) - set(tc.id for tc in valid_preconditions)
                if invalid_ids:
                    return jsonify({'error': f'Precondition test cases not found: {list(invalid_ids)}'}), 404
                    
                testcase.precondition_test_cases = valid_preconditions
        
        # 处理测试套件
        if 'test_suite_ids' in data:
            test_suite_ids = data['test_suite_ids']
            if test_suite_ids is None:
                testcase.test_suites = []
            elif isinstance(test_suite_ids, list):
                valid_suites = TestSuite.query.filter(TestSuite.id.in_(test_suite_ids), TestSuite.is_deleted==False).all()
                invalid_ids = set(test_suite_ids) - set(ts.id for ts in valid_suites)
                if invalid_ids:
                    return jsonify({'error': f'Test suites not found: {list(invalid_ids)}'}), 404
                    
                testcase.test_suites = valid_suites
        
        db.session.commit()
        return jsonify(testcase.to_dict())
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

@app.route('/api/testcases/<int:testcase_id>', methods=['DELETE'])
def delete_testcase(testcase_id):
    """
    删除测试用例（逻辑删除）
    """
    try:
        # 标记为已删除而不是物理删除
        testcase = TestCase.query.filter_by(id=testcase_id, is_deleted=False).first_or_404()
        testcase.is_deleted = True
        db.session.commit()
        return '', 204
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

@app.route('/testsuites')
def testsuites():
    """
    测试套件列表页面
    """
    return render_template('testsuites.html')

@app.route('/api/testsuites', methods=['GET'])
def get_testsuites():
    """
    获取所有测试套件
    """
    try:
        # 只获取未删除的测试套件
        all_testsuites = TestSuite.query.filter_by(is_deleted=False).all()
        return jsonify([ts.to_dict() for ts in all_testsuites])
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/api/testsuites', methods=['POST'])
def create_testsuite():
    """
    创建测试套件
    """
    try:
        data = request.get_json()
        
        # 验证必要字段
        if not data.get('name'):
            return jsonify({'error': 'Name is required'}), 400
            
        testsuite = TestSuite(
            name=data.get('name'),
            description=data.get('description', '')
        )
        
        # 处理关联测试用例
        test_case_ids = data.get('test_case_ids', [])
        if test_case_ids:
            # 查询有效的测试用例
            valid_testcases = TestCase.query.filter(TestCase.id.in_(test_case_ids), TestCase.is_deleted==False).all()
            # 获取无效的ID
            invalid_ids = set(test_case_ids) - set(tc.id for tc in valid_testcases)
            if invalid_ids:
                return jsonify({'error': f'Test cases not found: {list(invalid_ids)}'}), 404
                
            testsuite.test_cases.extend(valid_testcases)
        
        db.session.add(testsuite)
        db.session.commit()
        
        # 返回包含关联测试用例的完整信息
        return jsonify(testsuite.to_dict()), 201
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

@app.route('/api/testsuites/<int:suite_id>', methods=['GET'])
def get_testsuite(suite_id):
    """
    获取单个测试套件
    """
    try:
        # 只获取未删除的测试套件
        testsuite = TestSuite.query.filter_by(id=suite_id, is_deleted=False).first_or_404()
        return jsonify(testsuite.to_dict())
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/api/testsuites/<int:suite_id>', methods=['PUT'])
def update_testsuite(suite_id):
    """
    更新测试套件
    """
    try:
        # 只更新未删除的测试套件
        testsuite = TestSuite.query.filter_by(id=suite_id, is_deleted=False).first_or_404()
        data = request.get_json()
        
        # 更新基本信息
        if data.get('name'):
            testsuite.name = data['name']
        testsuite.description = data.get('description', testsuite.description)
        
        # 处理关联测试用例
        if 'test_case_ids' in data:
            test_case_ids = data['test_case_ids']
            if test_case_ids is None:  # 允许清空关联用例
                testsuite.test_cases = []
            elif isinstance(test_case_ids, list):
                # 查询有效的测试用例
                valid_testcases = TestCase.query.filter(TestCase.id.in_(test_case_ids), TestCase.is_deleted==False).all()
                # 获取无效的ID
                invalid_ids = set(test_case_ids) - set(tc.id for tc in valid_testcases)
                if invalid_ids:
                    return jsonify({'error': f'Test cases not found: {list(invalid_ids)}'}), 404
                    
                testsuite.test_cases = valid_testcases
        
        db.session.commit()
        
        # 返回包含关联测试用例的完整信息
        return jsonify(testsuite.to_dict())
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

@app.route('/api/testsuites/<int:suite_id>', methods=['DELETE'])
def delete_testsuite(suite_id):
    """
    删除测试套件（逻辑删除）
    """
    try:
        # 标记为已删除而不是物理删除
        testsuite = TestSuite.query.filter_by(id=suite_id, is_deleted=False).first_or_404()
        testsuite.is_deleted = True
        db.session.commit()
        return '', 204
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

@app.route('/api/testcases/<int:testcase_id>/execute', methods=['POST'])
def execute_testcase(testcase_id):
    """执行测试用例"""
    try:
        # 获取测试用例
        testcase = TestCase.query.get_or_404(testcase_id)
        if testcase.is_deleted:
            return jsonify({'error': '测试用例已被删除'}), 404
        
        # 获取浏览器类型
        data = request.get_json()
        browser = data.get('browser', 'edge')
        
        # 导入测试执行器并执行测试用例
        from ..controllers.test_executor import TestExecutor
        executor = TestExecutor(browser)
        result = executor.execute_test_case(testcase)
        
        return jsonify(result.to_dict())
    except Exception as e:
        error_msg = f"执行测试用例失败: {str(e)}\n{traceback.format_exc()}"
        print(error_msg)
        return jsonify({'error': str(e)}), 500

@app.route('/api/testsuites/<int:suite_id>/execute', methods=['POST'])
def execute_testsuite(suite_id):
    """执行测试套件"""
    try:
        # 获取测试套件
        testsuite = TestSuite.query.get_or_404(suite_id)
        if testsuite.is_deleted:
            return jsonify({'error': '测试套件已被删除'}), 404
        
        # 获取浏览器类型
        data = request.get_json()
        browser = data.get('browser', 'edge')
        
        # 导入测试执行器并执行测试套件
        from ..controllers.test_executor import TestExecutor
        executor = TestExecutor(browser)
        result = executor.execute_test_suite(testsuite)
        
        return jsonify(result)
    except Exception as e:
        error_msg = f"执行测试套件失败: {str(e)}\n{traceback.format_exc()}"
        print(error_msg)
        return jsonify({'error': str(e)}), 500

@app.route('/testresults')
def testresults():
    """
    测试结果页面
    """
    from datetime import datetime
    current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    return render_template('testresults.html', date=current_time)

@app.route('/api/testresults', methods=['GET'])
def get_testresults():
    """
    获取测试结果
    支持按日期筛选: ?date=2023-11-15
    """
    try:
        # 获取查询参数
        date_filter = request.args.get('date')
        
        # 构建查询
        query = TestResult.query
        
        # 如果提供了日期参数，则按日期筛选
        if date_filter:
            try:
                # 将字符串日期转换为datetime对象
                from datetime import datetime
                filter_date = datetime.strptime(date_filter, '%Y-%m-%d')
                # 获取当天的开始和结束时间
                start_of_day = filter_date.replace(hour=0, minute=0, second=0, microsecond=0)
                end_of_day = filter_date.replace(hour=23, minute=59, second=59, microsecond=999999)
                
                # 添加日期范围筛选
                query = query.filter(
                    TestResult.executed_at >= start_of_day,
                    TestResult.executed_at <= end_of_day
                )
            except ValueError:
                # 如果日期格式不正确，返回错误
                return jsonify({'error': '日期格式不正确，应为 YYYY-MM-DD'}), 400
        
        # 执行查询并按执行时间倒序排列
        results = query.order_by(TestResult.executed_at.desc()).all()
        return jsonify([tr.to_dict() for tr in results])
    except Exception as e:
        return jsonify({'error': str(e)}), 500
